import axios, {AxiosError, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse} from 'axios';
import {useRouter} from 'vue-router'
import {ElMessage} from 'element-plus'

class client {
    private instance: AxiosInstance;
    private executed = false;

    constructor(config: AxiosRequestConfig) {
        this.instance = axios.create(config);
        this.interceptors();
    }

    public async request<T, D = IResponseResult<T>>(config: AxiosRequestConfig) {
        return new Promise(async (resolve, reject) => {
            try {
                const response = await this.instance.request<D>(config);
                resolve(response.data);
            } catch (error) {
                reject(error);
            }
        }) as Promise<D>;
    }

    public async originalRequest<T, D = T>(config: AxiosRequestConfig) {
        return new Promise(async (resolve, reject) => {
            try {
                const response = await this.instance.request<D>(config);
                resolve(response);
            } catch (error) {
                reject(error);
            }
        }) as Promise<AxiosResponse<D>>;
    }

    private interceptors() {
        this.interceptorsRequest();
        this.interceptorsResponse();
    }

    private interceptorsRequest() {
        this.instance.interceptors.request.use(
            (config) => {
                const token = window.localStorage.getItem("token");
                if (token) {
                    // @ts-ignore
                    config.headers.token = token;
                }
                return config;
            },
            (error: AxiosError) => {
                ElMessage.error("发送请求异常，请检查网络后重试！");
                return Promise.reject(error);
            }
        );
    }

    private interceptorsResponse() {
        this.instance.interceptors.response.use(
            (response) => {
                const data: IResponseResult<unknown> = response.data;
                if (data.msg && data.msg !== "" && data.success) {
                    ElMessage.success(data.msg);
                } else if (data.msg && data.msg !== "" && !data.success) {
                    ElMessage.error(data.msg);
                }
                return response;
            },
            (error: AxiosError) => {
                // @ts-ignore
                const {status} = error.response;
                switch (status) {
                    case 400:
                        ElMessage.error("请求体错误！");
                        break;
                    case 401:
                        if (!this.executed) {
                            this.executed = true;
                            ElMessage.error("未登录或登录状态失效，请先登录");
                            useRouter().push("login").then()
                            setTimeout(() => {
                                this.executed = false;
                            }, 1000)
                        }
                        break;
                    case 403:
                        ElMessage.warning("您没有权限!");
                        break;
                    case 404:
                        ElMessage.error("访问资源不存在！");
                        break;
                    case 405:
                        ElMessage.warning("请求方式错误!");
                        break;
                    case 500:
                        ElMessage.error("服务器开小差了，请稍后重试");
                        break;
                    case 503:
                        ElMessage.warning("服务器正在维护中，请稍后再试");
                        break;
                }
                return Promise.reject(error);
            }
        );
    }
}

const http = new client({
    baseURL: '',
    timeout: 10000,
    withCredentials: true,
    headers: {
        'Content-Type': 'application/json;charset=UTF-8'
    }
})

export default http;